namespace SimpleWebServices.Web.UI.Html
{
    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    using System.Xml.XPath;
    using SimpleWebServices;
    using SimpleWebServices.Web.UI.Html.Elements;
    using Xunit;

    public sealed class InnerElementsFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<InnerElements>()
                .DerivesFrom<Element>()
                .IsAbstractBaseClass()
                .XmlRoot("element")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            InnerElementsDerived expected = new InnerElementsDerived
            {
                Id = "token",
                Class = "class",
                Language = "fr",
                Title = "title",
                Elements =
                {
                    new TextString("Some text"),
                    new LineBreak(),
                    new Image { Source = new Uri("/image.png", UriKind.Relative) }
                }
            };

            string xml =
                "<element class='class' id='token' lang='fr' title='title'>" +
                    "Some text" +
                    "<br />" +
                    "<img src='/image.png' />" +
                "</element>";
            InnerElementsDerived actual = xml.Deserialize<InnerElementsDerived>();

            Assert.Equal<string>(expected.ToString(), actual.ToString());
        }

        [Fact]
        public void serialize()
        {
            InnerElementsDerived obj = new InnerElementsDerived
            {
                Id = "token",
                Class = "class",
                Language = "fr",
                Title = "title",
                Elements =
                {
                    new TextString("Some text"),
                    new LineBreak(),
                    new Image { Source = new Uri("/image.png", UriKind.Relative) }
                }
            };

            XPathNavigator navigator = obj.Serialize().CreateNavigator();

            Assert.True((bool)navigator.Evaluate("1=count(/element[@id='token'][text()='Some text'])"));
            Assert.True((bool)navigator.Evaluate("1=count(/element/br)"));
            Assert.True((bool)navigator.Evaluate("1=count(/element/img[@src='/image.png'])"));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new InnerElementsDerived() as InnerElements);
        }

        [Fact]
        public void prop_InnerElements()
        {
            Assert.True(new PropertyExpectations(typeof(InnerElementsDerived).GetProperty("Elements"))
                .DefaultValueIsNotNull()
                .TypeIs<IList<IElementSerializable>>()
                .Result);
        }

        [Fact]
        public void op_Add_LabelledOfT()
        {
            LabelledControl expected = new LabelledControl(new Select("example"), "text");

            InnerElements obj = new InnerElementsDerived();
            obj.Add(expected);

            Assert.Same(expected.Label, obj.Elements[0]);
        }

        [Fact]
        public void indexer_string_get()
        {
            InnerElementsDerived actual = (
                "<element>" +
                    "<div id='example' class='test' />" +
                "</element>").Deserialize<InnerElementsDerived>();

            Assert.Equal<string>("test", actual["example"].Class);
        }

        [Fact]
        public void indexer_string_getThis()
        {
            InnerElementsDerived actual = "<element id='example' class='test' />".Deserialize<InnerElementsDerived>();

            Assert.Equal<string>("test", actual["example"].Class);
        }
    }
}